home *** CD-ROM | disk | FTP | other *** search
- /*
- * This software is copyright 1992 by Robert Morris.
- * You may freely redistribute this software as shareware
- * if you do so in the same form as you got it. If you find
- * this software useful, please send $12 to:
- * Robert Morris
- * P.O. Box 1044
- * Harvard Square Station
- * Cambridge, MA 02238
- * ecognome@aol.com
- * If you incorporate any of this software in any kind of
- * commercial product, please send $2 per copy distributed
- * to the above address.
- */
-
- /*
- * TIFFWindow file, windowStyle, visible, depth, customPalette
- *
- * If no file is supplied, or if the file is "", TIFFWindow prompts the user.
- * It uses hypercard's file search path.
- *
- * WindowStyle has no effect right now.
- *
- * Visible controls whether the window starts out visible.
- *
- * Depth sets the depth of the off-screen buffer; such a buffer greatly improves
- * redraw and scroll speed. 0 means no buffer
- * at all: all drawing is done from the disk. Only 0, 16 and 32 are universal; 1, 2, 4,
- * and 8 only work well if the TIFF image is actually that depth.
- * TIFFWindow will reduce the off-screen depth to the depth of the TIFF image.
- * If there is not enough memory, it won't use an off-screen buffer.
- *
- * CustomPalette is true, a cpmt resource number, or false. The default is true,
- * which causes TIFFWindow to call the Picture Utilities to compute a reasonable
- * palette for the deepest CLUT screen at the time when TIFFWindow is called.
- * A number indicates the resource number of a custom sampling method.
- * False means use the color map in the TIFF file, or none if there was none.
- * Computing a palette can take a few seconds. Custom palettes only work with
- * an off-screen buffer.
- *
- * If the result is not empty, it contains an error message. TIFFWindow usually
- * produces an error message if it doesn't understand the TIFF file format, but
- * occasionally it doesn't find this out until too late, in which case it will
- * display an empty window.
- *
- * The dithering property controls dithering. This only works well from an off-screen
- * graphics buffer.
- *
- * The scrollbars property controls whether scrollbars are visible.
- *
- * The picturewidth and pictureheight properties yield the size of the image
- * in pixels.
- *
- * The scale property, a number, controls zooming of the image. Each displayed
- * pixel represents a square 2^scale pixels on a side in the original. So, for
- * instance, a scale of 0 (the default) means no change, 1 means double the image
- * size, and -1 means halve it.
- *
- * The picturedepth property yields the pixel depth of the TIFF image.
- *
- * If the user clicks on the picture, TIFFWindow sends to HyperTalk messages,
- * one when the user presses the mouse button, and one when he or she releases
- * the button. The messages are MouseDownInPicture and MouseUpInPicture. The
- * messages have two arguments, the window name and the image coordinates.
- */
-
- #include <HyperXCmd.h>
- #include <stdlib.h>
- #include "SetUpA4.h"
- #include <string.h>
- #include <ctype.h>
- #include "tiffinfo.h"
- #include <QDOffscreen.h>
- #include <Palette.h>
- #include <PictUtil.h>
-
- typedef struct thunk{
- TIFFPtr ti;
- CGrafPtr gw; /* off-screen graphics world */
- ControlHandle hScroll, vScroll;
- int ref; /* keep the file open */
- Boolean active;
-
- /* properties */
- Boolean visible;
- Boolean scrollbars;
- int depth; /* desired off-screen depth, or 0 for none */
- double scale;
- Boolean dither;
- Boolean customPalette;
- Boolean customMethod;
- } ThunkRec, **Thunk;
-
- Thunk th;
- WindowPtr w;
- XCmdPtr xptr;
-
- #define SBWIDTH 15
-
- void InitPalette(void);
- void DisposeThunk(Thunk);
- Handle HStr(char *);
- int pstrcmp(StringPtr, StringPtr);
- int SetUpWindow(StringPtr);
- void UpdateWindow(void);
- void DoContent(EventRecord *theEvent);
- void MyGrowWindow(Point);
- int cmp(char *, char *);
- void FileOfPath(StringPtr path, StringPtr file);
- OSErr CopyToGWorld();
- int FixDepth(int depth);
- Boolean SetProp(StringPtr prop, Handle h);
- Handle GetProp(StringPtr prop);
- int DeepestCLUTScreen();
- long myatoi(char *);
- Point MaxWindowSize();
- void MySizeWindow(short width, short height);
- double myatof(char *s);
- double OldScaleToNew(int scale);
- int NewScaleToOld(double scale);
- void myftoa(double d, char *s);
- void myitoa(long i, char *a);
-
- /* there was no GetGWorldPixMap() before System 7 */
- #define GWPM(gw) (HasSystem7() ? GetGWorldPixMap(gw) : (gw)->portPixMap)
-
- pascal void
- main(paramPtr)
- XCmdPtr paramPtr;
- {
- XWEventInfoPtr ei;
- WindowPtr whichWindow;
- GrafPtr oport;
- int theChar, err, ref, vref, findCode;
- Point pt;
- Rect r;
- char **h;
- StringPtr prop;
- Str255 tmp, fullname, ttl;
- PaletteHandle pltt;
- Thunk oth;
- WindowPtr ow;
- XCmdPtr oxptr;
- SFReply sf;
- SFTypeList types;
- OSType type;
- CGrafPtr agw;
-
- RememberA0();
- SetUpA4();
-
- /* save old values */
- oth = th;
- ow = w;
- oxptr = xptr;
-
- xptr = paramPtr;
-
- if(paramPtr->paramCount == -1){
- /* it's a window event */
- ei = (XWEventInfoPtr) (paramPtr->params[0]);
- w = ei->eventWindow;
- th = (Thunk) GetWRefCon(w);
- if(th == 0){
- paramPtr->passFlag = TRUE;
- goto out;
- }
-
- GetPort(&oport);
- SetPort(w);
-
- switch(ei->event.what){
- case xOpenEvt:
- XWAllowReEntrancy(paramPtr, w, TRUE, TRUE);
- if((*th)->visible)
- SelectWindow(w); /* if I don't do this, it's not highlighted... */
- break;
- case xCloseEvt:
- XWAllowReEntrancy(paramPtr, w, FALSE, FALSE);
- DisposeThunk(th);
- SetWRefCon(w, 0L);
- if(HasColorQD() && (pltt = GetPalette(w))){
- SetPalette(w, 0L, FALSE);
- DisposePalette(pltt);
- }
- paramPtr->passFlag = TRUE; /* yes, we're willing to close */
- break;
- case xCursorWithin:
- paramPtr->passFlag = TRUE; /* ask HyperCard for an arrow cursor */
- break;
- case xSetPropEvt:
- paramPtr->passFlag = !SetProp((StringPtr)ei->eventParams[0],
- (Handle)ei->eventParams[1]);
- break;
- case xGetPropEvt:
- h = GetProp((StringPtr) (ei->eventParams[0]));
- if(h){
- ei->eventResult = h;
- paramPtr->passFlag = FALSE;
- } else {
- paramPtr->passFlag = TRUE; /* ask HyperCard to handle it for us */
- ei->eventResult = (char **) 0;
- }
- break;
- case xGiveUpEditEvt:
- EndXWEdit(paramPtr, w);
- break;
- case xEditUndo:
- /* what should I do here? */
- break;
- case xEditCut:
- break;
- case xEditCopy:
- break;
- case xEditPaste:
- break;
- case xEditClear:
- break;
- case nullEvent:
- break;
- case activateEvt:
- if((*th)->scrollbars){
- if (ei->event.modifiers & activeFlag) {
- ShowControl((*th)->vScroll);
- ShowControl((*th)->hScroll);
- (*th)->active = TRUE;
- } else {
- HideControl((*th)->vScroll);
- HideControl((*th)->hScroll);
- (*th)->active = FALSE;
- }
- DrawGrowIcon(w);
- }
- break;
- case mouseDown:
- switch(findCode = FindWindow(ei->event.where, &whichWindow)){
- case inGoAway:
- if(TrackGoAway(w, ei->event.where)){
- CloseXWindow(paramPtr, w); /* ask HyperCard to close us */
- }
- break;
- case inDrag:
- /*
- * ask HyperCard to deal with moving the window. this is
- * an undocumented feature as of B39.
- */
- paramPtr->passFlag = TRUE;
- break;
- case inContent:
- DoContent(&(ei->event));
- break;
- case inGrow:
- MyGrowWindow(ei->event.where);
- break;
- case inZoomIn:
- case inZoomOut:
- if(TrackBox(w, ei->event.where, findCode) == TRUE){
- ZoomWindow(w, findCode, TRUE);
- FixScrollBars();
- }
- break;
- }
- break;
- case keyDown:
- case autoKey:
- theChar = ei->event.message & charCodeMask;
- if ((ei->event.modifiers & cmdKey) != 0){
- } else {
- }
- break;
- case updateEvt:
- UpdateWindow();
- break;
- }
-
- SetPort(oport);
- } else {
- th = (Thunk) NewHandle((long) sizeof(**th));
- if(th == 0){
- paramPtr->returnValue = HStr("out of memory");
- goto out;
- }
- (*th)->ref = -1;
- (*th)->ti = 0;
- (*th)->gw = 0;
- (*th)->hScroll = (*th)->vScroll = 0;
- (*th)->active = FALSE;
- (*th)->visible = TRUE;
- (*th)->scrollbars = TRUE;
- (*th)->depth = 32;
- (*th)->dither = FALSE;
- (*th)->scale = 1;
- (*th)->customPalette = TRUE;
- (*th)->customMethod = systemMethod;
-
- if(paramPtr->paramCount > 2 && cmp(*(paramPtr->params[2]), "true") != 1)
- (*th)->visible = FALSE;
-
- if(paramPtr->paramCount > 3)
- (*th)->depth = myatoi(*(paramPtr->params[3]));
-
- if(paramPtr->paramCount > 4){
- if(cmp(*(paramPtr->params[4]), "true")){
- (*th)->customPalette = TRUE;
- (*th)->customMethod = systemMethod;
- } else if(cmp(*(paramPtr->params[4]), "false")){
- (*th)->customPalette = FALSE;
- } else {
- (*th)->customPalette = TRUE;
- (*th)->customMethod = myatoi(*(paramPtr->params[4]));
- }
- }
-
- if(paramPtr->paramCount > 0 && (*(paramPtr->params[0]))[0] != '\0'){
- strncpy((char *)tmp, *(paramPtr->params[0]), sizeof(tmp) - 1);
- CtoPstr(tmp);
- types[0] = 'TIFF';
- type = 'TIFF';
- if(GetFilePath(xptr, tmp, -1, types, TRUE, &type, fullname) != TRUE){
- paramPtr->returnValue = HStr("cannot find file");
- goto out;
- }
- err = FSOpen(fullname, 0, &ref);
- FileOfPath(fullname, ttl);
- } else {
- pt.h = pt.v = 75;
- types[0] = 'TIFF';
- SFGetFile(pt, "\pWhat TIFF file?", 0L, 1, types, 0L, &sf);
- if(sf.good == 0){
- paramPtr->returnValue = HStr("cancel");
- goto out;
- }
- err = FSOpen(sf.fName, sf.vRefNum, &ref);
- FileOfPath(sf.fName, ttl);
- }
- if(err != 0){
- DisposeThunk(th);
- paramPtr->returnValue = HStr("cannot open file");
- goto out;
- }
- (*th)->ref = ref;
-
- (*th)->ti = ScanTIFF((*th)->ref);
- if((*th)->ti == 0 || GetTIFFError((*th)->ti, tmp) != 0){
- DisposeThunk(th);
- paramPtr->returnValue = HStr("cannot understand TIFF file");
- goto out;
- }
-
- if(TIFFDrawable((*th)->ti) == FALSE){
- DisposeThunk(th);
- paramPtr->returnValue = HStr("Cannot draw the picture on this Macintosh.");
- goto out;
- }
-
- /* attempt to set up an off-screen copy */
- if((*th)->depth > 0 && HasQD32()){
- /* eliminate excess depth */
- if((*th)->ti->samplesPerPixel == 1 &&
- (*th)->ti->bitsPerSample[0] < (*th)->depth){
- (*th)->depth = FixDepth((*th)->ti->bitsPerSample[0]);
- }
-
- r.left = 0;
- r.right = (*th)->ti->imageWidth;
- r.top = 0;
- r.bottom = (*th)->ti->imageLength;
-
- err = NewGWorld(&agw, (*th)->depth, &r, (*th)->ti->colorMap, 0L, 0);
- if(err == 0){
- (*th)->gw = agw;
- if((err = CopyToGWorld()) != 0){
- if(GetTIFFError((*th)->ti, tmp) != 0 && tmp[0] != 0)
- paramPtr->returnValue = PasToZero(xptr, tmp);
- else if(err == memFullErr)
- paramPtr->returnValue = HStr("out of memory");
- else
- paramPtr->returnValue = HStr("could not understand TIFF file");
- DisposeThunk(th);
- goto out;
- }
- FSClose((*th)->ref);
- (*th)->ref = -1;
- }
- }
-
- if(SetUpWindow(ttl) < 0){
- DisposeThunk(th);
- paramPtr->returnValue = HStr("window creation failed");
- goto out;
- }
-
- InitPalette();
- }
-
- out:
- /* restore old globals in case of reentrance */
- xptr = oxptr;
- w = ow;
- th = oth;
-
- RestoreA4();
- }
-
- OSErr
- CopyToGWorld()
- {
- CGrafPtr oldPort;
- GDHandle oldGD;
- PixMapHandle pm;
- OSErr err;
- Rect r;
-
- GetGWorld(&oldPort, &oldGD);
-
- SetGWorld((*th)->gw, 0);
- pm = GWPM((*th)->gw);
- if(LockPixels(pm) != TRUE){
- SetGWorld(oldPort, oldGD);
- return(memFullErr);
- }
-
- r = (*th)->gw->portRect;
- err = DrawTIFF((*th)->ref, (*th)->ti, r, r, 0);
-
- UnlockPixels(pm);
- SetGWorld(oldPort, oldGD);
-
- return(err);
- }
-
- void
- DisposeThunk(Thunk th)
- {
- if(th){
- if((*th)->ti)
- DisposeTIFF((*th)->ti);
- (*th)->ti = 0;
- if((*th)->ref != -1)
- FSClose((*th)->ref);
- (*th)->ref = -1;
- if((*th)->gw)
- DisposeGWorld((*th)->gw);
- (*th)->gw = 0;
- DisposHandle(th);
- }
- }
-
- /*
- * returns < 0 if there was a problem.
- */
- int
- SetUpWindow(StringPtr ttl)
- {
- Rect wr, sr, r;
- GDHandle gd;
- int iheight, iwidth, wwidth, wheight;
- GrafPtr wmport;
-
- /*
- * Choose a window size: try to show the whole image, but stay on
- * the screen.
- */
- if(HasColorQD()){
- gd = GetMainDevice();
- sr = (*gd)->gdRect;
- } else {
- GetWMgrPort(&wmport);
- sr = wmport->portRect;
- }
-
- iwidth = (*th)->ti->imageWidth;
- iheight = (*th)->ti->imageLength;
-
- #define MIN(a, b) ((a) < (b) ? (a) : (b))
- wwidth = MIN(iwidth+SBWIDTH, sr.right - sr.left - 40);
- wheight = MIN(iheight+SBWIDTH, sr.bottom - sr.top - 70);
-
- wr.left = ((sr.right - sr.left) / 2) - (wwidth / 2);
- wr.right = wr.left + wwidth;
- wr.top = ((sr.bottom - sr.top - 30) / 2) - (wheight / 2) + 30;
- wr.bottom = wr.top + wheight;
-
- w = NewXWindow(xptr,
- &wr,
- ttl, /* title */
- (*th)->visible,
- documentProc,
- HasColorQD(), /* color? */
- FALSE); /* floating? */
-
-
- if(w == 0)
- return(-1);
-
- SetWRefCon(w, (long)th);
-
- r.right = wr.right;
- r.left = r.right - SBWIDTH;
- r.top = wr.top;
- r.bottom = wr.bottom;
- (*th)->vScroll = NewControl(w, &r, "", TRUE, 0, 0, 1, scrollBarProc, 0L);
-
- r.left = wr.left;
- r.right = wr.right;
- r.bottom = wr.bottom;
- r.top = r.bottom - SBWIDTH;
- (*th)->hScroll = NewControl(w, &r, "", TRUE, 0, 0, 1, scrollBarProc, 0L);
-
- FixScrollBars();
-
- return(0);
- }
-
- /*
- * the window has changed size, and the scroll bars will have to be
- * resized, and their max and min values re-set.
- */
- FixScrollBars()
- {
- Rect wr, r;
- int oh, ov, iheight, iwidth, wheight, wwidth;
-
- wr = w->portRect;
-
- iheight = (*th)->ti->imageLength;
- iwidth = (*th)->ti->imageWidth;
-
- HideControl((*th)->vScroll);
- HideControl((*th)->hScroll);
-
- oh = GetCtlValue((*th)->hScroll);
- ov = GetCtlValue((*th)->vScroll);
-
- #define MAX(a, b) ((a) > (b) ? (a) : (b))
- wheight = UnScaleIt(wr.bottom - wr.top - ((*th)->scrollbars ? SBWIDTH : 0));
- SetCtlMin((*th)->vScroll, 0);
- SetCtlMax((*th)->vScroll, MAX(0, iheight - wheight));
-
- wwidth = UnScaleIt(wr.right - wr.left - ((*th)->scrollbars ? SBWIDTH : 0));
- SetCtlMin((*th)->hScroll, 0);
- SetCtlMax((*th)->hScroll, MAX(0, iwidth - wwidth));
-
- if(oh != GetCtlValue((*th)->hScroll) || ov != GetCtlValue((*th)->vScroll)){
- InvalRect(&(w->portRect));
- }
-
- MoveControl((*th)->vScroll, wr.right - SBWIDTH, wr.top - 1);
- SizeControl((*th)->vScroll, SBWIDTH+1, wr.bottom - wr.top - SBWIDTH + 2);
-
- MoveControl((*th)->hScroll, wr.left - 1, wr.bottom - SBWIDTH);
- SizeControl((*th)->hScroll, wr.right - wr.left - SBWIDTH + 2, SBWIDTH+1);
-
- if((*th)->scrollbars){
- if((*th)->active){
- ShowControl((*th)->vScroll);
- ShowControl((*th)->hScroll);
- DrawGrowIcon(w);
- }
- }
- }
-
- int
- UnScaleIt(x)
- int x;
- {
- return(x / (*th)->scale);
- }
-
- int
- ScaleIt(x)
- int x;
- {
- return(x * (*th)->scale);
- }
-
- double
- OldScaleToNew(int scale)
- {
- double x;
- int i;
-
- x = 1;
- /* calculate how to scale the picture */
- if(scale > 0){
- for(i = 0; i < scale; i++)
- x *= 2;
- } else if(scale < 0){
- for(i = 0; i > scale; --i)
- x /= 2;
- }
-
- return(x);
- }
-
- int
- NewScaleToOld(double scale)
- {
- long i, x, sign;
-
- if(scale <= 0.0)
- return(0);
-
- if(scale < 1.0){
- scale = 1 / scale;
- sign = -1;
- } else
- sign = 1;
-
- x = 1;
- for(i = 0; x < scale && i < 32; i++, x *= 2)
- ;
- return(i * sign);
- }
-
- void
- UpdateWindow()
- {
- BeginUpdate( w );
-
- DrawControls( w );
- if((*th)->scrollbars)
- DrawGrowIcon( w );
- ReDraw();
-
- EndUpdate( w );
- }
-
- ReDraw()
- {
- Rect ir, dr, gr;
- int xoff, yoff, dh, dv;
- PixMapHandle pm;
-
- xoff = GetCtlValue((*th)->hScroll);
- yoff = GetCtlValue((*th)->vScroll);
-
- ir.left = xoff;
- ir.top = yoff;
- ir.right = (*th)->ti->imageWidth;
- ir.bottom = (*th)->ti->imageLength;
-
- dr = w->portRect;
- dr.right = dr.left + ScaleIt(ir.right - ir.left);
- dr.bottom = dr.top + ScaleIt(ir.bottom - ir.top);
-
- dh = dr.right - (w->portRect.right - ((*th)->scrollbars ? SBWIDTH : 0));
- if(dh > 0){
- dr.right -= dh;
- ir.right -= UnScaleIt(dh);
- }
- dv = dr.bottom - (w->portRect.bottom - ((*th)->scrollbars ? SBWIDTH : 0));
- if(dv > 0){
- dr.bottom -= dv;
- ir.bottom -= UnScaleIt(dv);
- }
-
- if((*th)->gw){
- pm = GWPM((*th)->gw);
- LockPixels(pm);
- CopyBits(*pm, &(w->portBits), &ir, &dr,
- (*th)->dither ? 64 : srcCopy, 0L);
- UnlockPixels(pm);
- } else if((*th)->ref != -1){
- DrawTIFF((*th)->ref, (*th)->ti, ir, dr, (*th)->dither);
- }
-
- /* now gray out invalid parts of the window */
- gr.left = dr.right;
- gr.right = w->portRect.right - ((*th)->scrollbars ? SBWIDTH : 0);
- gr.top = 0;
- gr.bottom = w->portRect.bottom - ((*th)->scrollbars ? SBWIDTH : 0);
- FillRect(&gr, &gray);
-
- gr.left = 0;
- gr.top = dr.bottom;
- FillRect(&gr, &gray);
- }
-
- /*
- * Give the window an appropriate palette. Such a palette should have a separate
- * set of colors for each different depth CLUT device the window intersects.
- * This is possible using inhibited entries, but would be expensive since it
- * would require multiple calls to GetPixMapInfo(). And the palette might have
- * to be recomputed whenever the user moves the window onto a different screen
- * or changes the depth with the Monitors control panel.
- *
- * It would be nice if the color sampling methods used by GetPixMapInfo() returned
- * a palette with the most important colors first, or with multiple sets of
- * inhibited colors; such a palette would be useful at multiple depths.
- *
- * This routine computes a palette for the deepest CLUT device existing at the
- * time the TIFF window was created. This isn't perfect; the user might put
- * the window on a shallower screen, or change the depth.
- *
- * InitPalette the color map in the TIFF file if it can. Otherwise it uses the
- * Picture Utilities. The sampling method cpmt resource number can be set with
- * the 5th argument to TIFFWindow.
- */
- void
- InitPalette()
- {
- CTabHandle cth;
- PaletteHandle pltt = 0, opltt;
- PictInfo pi;
- PixMapHandle pm;
- OSErr err;
- int deepest, size;
-
- if(HasColorQD() == 0)
- return;
-
- deepest = DeepestCLUTScreen();
- size = DepthToSize(deepest);
-
- /*
- * Don't bother if there are no color CLUT screens.
- */
- if(deepest <= 1)
- return;
-
- if((cth = (*th)->ti->colorMap) && ((*cth)->ctSize+1) <= size){
- /*
- * Use the color map in the TIFF file if it isn't too large.
- */
- pltt = NewPalette((*cth)->ctSize + 1, cth, pmTolerant, 0);
- } else if(((*th)->ti->samplesPerPixel > 1 || (*th)->ti->bitsPerSample[0] > 1) &&
- (*th)->customPalette && (*th)->gw && HasSystem7()){
- pm = GWPM((*th)->gw);
- if(LockPixels(pm) == TRUE){
- err = GetPixMapInfo(pm, &pi, returnPalette|suppressBlackAndWhite,
- size - 2, (*th)->customMethod, 0);
- if(err == 0){
- pltt = pi.thePalette;
- pi.thePalette = 0;
- }
- UnlockPixels(pm);
- }
- }
-
- if(pltt)
- SetPalette(w, pltt, TRUE);
- }
-
- /*
- * Return the depth of the deepest CLUT screen, or zero if there are no
- * CLUT screens.
- */
- int
- DeepestCLUTScreen()
- {
- GDHandle gd;
- int depth = 0;
- PixMapHandle pm;
-
- gd = GetDeviceList();
- while(gd){
- if(TestDeviceAttribute(gd, screenDevice) == TRUE &&
- TestDeviceAttribute(gd, screenActive) == TRUE &&
- (*gd)->gdType == 0){
- pm = (*gd)->gdPMap;
- if(pm && (*pm)->cmpCount == 1 && (*pm)->cmpSize > depth)
- depth = (*pm)->cmpSize;
- }
- gd = GetNextDevice(gd);
- }
-
- return(depth);
- }
-
- int
- DepthToSize(int depth)
- {
- switch(depth){
- case 1: return(2);
- case 2: return(4);
- case 4: return(16);
- default: return(256);
- }
- }
-
- pascal void
- TrackIt(ctl, part)
- ControlHandle ctl;
- int part;
- {
- int amount, pagesize;
-
- if(ctl == (*th)->hScroll)
- pagesize = UnScaleIt((w->portRect.right - w->portRect.left) / 2);
- else
- pagesize = UnScaleIt((w->portRect.bottom - w->portRect.top) / 2);
-
- switch (part){
- case inUpButton:
- amount = -4;
- break;
- case inDownButton:
- amount = 4;
- break;
- case inPageUp:
- amount = -pagesize;
- break;
- case inPageDown:
- amount = pagesize;
- break;
- default:
- return;
- }
-
- SetCtlValue(ctl, GetCtlValue(ctl) + amount);
- ReDraw();
- }
-
- void
- DoContent(EventRecord *theEvent)
- {
- Point pt;
- ControlHandle ctl;
- int part, x, y;
- char tmp[256], ttl[256], tmp1[64];
-
- if (w != FrontDocWindow(xptr)){
- SelectWindow(w);
- return;
- }
-
- pt = theEvent->where;
- GlobalToLocal(&pt);
- part = FindControl(pt, w, &ctl);
- if(part == inThumb){
- part = TrackControl(ctl, pt, 0L);
- if(part)
- ReDraw();
- } else if(part != 0){
- part = TrackControl(ctl, pt, TrackIt);
- } else {
- x = UnScaleIt(pt.h - w->portRect.left) + GetCtlValue((*th)->hScroll);
- y = UnScaleIt(pt.v - w->portRect.top) + GetCtlValue((*th)->vScroll);
-
- GetWTitle(w, ttl);
- PtoCstr(ttl);
-
- strcpy(tmp, "mouseDownInPicture \"");
- strcat(tmp, ttl);
- strcat(tmp, "\", \"");
- myitoa(x, tmp1);
- strcat(tmp, tmp1);
- strcat(tmp, ",");
- myitoa(y, tmp1);
- strcat(tmp, tmp1);
- strcat(tmp, "\"");
- CtoPstr(tmp);
-
- SendCardMessage(xptr, (StringPtr)tmp);
-
- while(StillDown() == TRUE)
- ;
-
- GetMouse(&pt);
- x = UnScaleIt(pt.h - w->portRect.left) + GetCtlValue((*th)->hScroll);
- y = UnScaleIt(pt.v - w->portRect.top) + GetCtlValue((*th)->vScroll);
-
- strcpy(tmp, "mouseUpInPicture \"");
- strcat(tmp, ttl);
- strcat(tmp, "\", \"");
- myitoa(x, tmp1);
- strcat(tmp, tmp1);
- strcat(tmp, ",");
- myitoa(y, tmp1);
- strcat(tmp, tmp1);
- strcat(tmp, "\"");
- CtoPstr(tmp);
-
- SendCardMessage(xptr, (StringPtr)tmp);
- }
- }
-
- Point
- MaxWindowSize()
- {
- Point pt;
- int iwidth, iheight;
-
- iwidth = (*th)->ti->imageWidth;
- iheight = (*th)->ti->imageLength;
-
- pt.h = ScaleIt(iwidth) +
- ((*th)->scrollbars ? SBWIDTH : 0);
- pt.v = ScaleIt(iheight) +
- ((*th)->scrollbars ? SBWIDTH : 0);
-
- return(pt);
- }
-
- void
- MyGrowWindow(p)
- Point p;
- {
- long theResult;
- Rect r;
- Point max;
-
- max = MaxWindowSize();
-
- SetRect(&r, 80, 80, max.h + 1, max.v + 1);
- theResult = GrowWindow( w, p, &r );
- if (theResult == 0)
- return;
-
- MySizeWindow(LoWord(theResult), HiWord(theResult));
- }
-
- /*
- * change the size of the window, making sure it's not bigger than the
- * displayed image, and making sure the old grow box is destroyed.
- */
- void
- MySizeWindow(short width, short height)
- {
- Point max;
- Rect r;
-
- max = MaxWindowSize();
- if(width > max.h)
- width = max.h;
- if(height > max.v)
- height = max.v;
-
- if((*th)->scrollbars){
- /* we want to make sure the old grow box is redrawn */
- r = w->portRect;
- r.left = r.right - SBWIDTH;
- r.top = r.bottom - SBWIDTH;
- InvalRect(&r);
- EraseRect(&r);
- }
-
- SizeWindow( w, width, height, TRUE);
- FixScrollBars();
- }
-
- /* case-insensitive pascal string compare */
- int
- pstrcmp(StringPtr a, StringPtr b)
- {
- int alen, blen;
-
- if(EqualString(a, b, FALSE, FALSE) == TRUE)
- return(0);
- return(1);
- }
-
- /* case-insensitive C string compare; returns 1 if equal */
- int
- cmp(char *a, char *b)
- {
- int i, ac, bc;
-
- for(i = 0; a[i] && b[i]; i++){
- ac = a[i];
- if(isupper(ac))
- ac = tolower(ac);
- bc = b[i];
- if(isupper(bc))
- bc = tolower(bc);
- if(ac != bc)
- return(0);
- }
- if(a[i] == b[i])
- return(1);
- return(0);
- }
-
- Handle
- HStr(str)
- char *str;
- {
- Handle newHndl;
-
- newHndl = (Handle) NewHandle((long) strlen(str) + 1);
- if(newHndl == 0)
- return(0);
- strcpy((char *) (*newHndl), str);
- return(newHndl);
- }
-
- void
- FileOfPath(StringPtr path, StringPtr file)
- {
- int i, len;
-
- /* search backwards for the last : */
- for(i = path[0] - 1; i >= 0; --i){
- if(path[i+1] == ':'){
- len = path[0] - i - 1;
- strncpy((char *) file+1, (char *)path + i + 2, len);
- file[0] = len;
- return;
- }
- }
-
- strncpy((char *)file+1, (char *)path+1, path[0]);
- file[0] = path[0];
- }
-
- /*
- * Take whatever depth the user provided and round it up to the nearest
- * legal QuickDraw depth.
- */
- int
- FixDepth(int depth)
- {
- if(depth < 1)
- return(0);
- if(depth <= 1)
- return(1);
- if(depth <= 2)
- return(2);
- if(depth <= 4)
- return(4);
- if(depth <= 8)
- return(8);
- if(depth <= 16)
- return(16);
- return(32);
- }
-
- /*
- * Returns TRUE if it could handle the property.
- */
- Boolean
- SetProp(StringPtr prop, Handle h)
- {
- Boolean handled = TRUE;
- Rect r;
- Point pt;
- Str255 tmp;
- int ndither;
- double nscale;
- Handle lh;
-
- MoveHHi(h);
- HLock(h);
-
- if(pstrcmp(prop, "\pdithering") == 0){
- ndither = cmp(*h, "true");
- if(HasQD32() == 0)
- ndither = FALSE;
- if(ndither != (*th)->dither){
- (*th)->dither = ndither;
- ReDraw();
- }
- } else if(pstrcmp(prop, "\pscrollbars") == 0){
- int nscrollbars = cmp(*h, "true");
- if((*th)->scrollbars != nscrollbars){
- (*th)->scrollbars = nscrollbars;
- r = w->portRect;
- if(nscrollbars == TRUE){
- /* make room for them */
- SizeWindow(w, r.right - r.left + SBWIDTH,
- r.bottom - r.top + SBWIDTH, TRUE);
- } else {
- /* get rid of them */
- SizeWindow(w, r.right - r.left - SBWIDTH,
- r.bottom - r.top - SBWIDTH, TRUE);
- }
- FixScrollBars();
- }
- } else if(pstrcmp(prop, "\pscale") == 0){
- nscale = OldScaleToNew(myatoi(*h));
- if(nscale != (*th)->scale){
- (*th)->scale = nscale;
- FixScrollBars();
- ReDraw();
- }
- } else if(pstrcmp(prop, "\pnscale") == 0){
- nscale = myatof(*h);
- if(nscale != (*th)->scale && nscale > 0.001){
- (*th)->scale = nscale;
- FixScrollBars();
- ReDraw();
- }
- } else if(pstrcmp(prop, "\pscroll") == 0){
- ZeroToPas(xptr, *h, tmp);
- StrToPoint(xptr, tmp, &pt);
- SetCtlValue((*th)->hScroll, pt.h);
- SetCtlValue((*th)->vScroll, pt.v);
- ReDraw();
- } else if(pstrcmp(prop, "\prect") == 0 || pstrcmp(prop, "\prectangle") == 0){
- ZeroToPas(xptr, *h, tmp);
- StrToRect(xptr, tmp, &r);
-
- lh = EvalExpr(xptr, "\pthe loc of the card window");
- ZeroToPas(xptr, *lh, tmp);
- StrToPoint(xptr, tmp, &pt);
- DisposHandle(h);
-
- OffsetRect(&r, pt.h, pt.v);
-
- MoveWindow(w, r.left, r.top, FALSE);
- MySizeWindow(r.right - r.left, r.bottom - r.top);
- } else if(pstrcmp(prop, "\pglobalrect") == 0){
- ZeroToPas(xptr, *h, tmp);
- StrToRect(xptr, tmp, &r);
-
- MoveWindow(w, r.left, r.top, FALSE);
- MySizeWindow(r.right - r.left, r.bottom - r.top);
- } else if(pstrcmp(prop, "\pgloballoc") == 0){
- ZeroToPas(xptr, *h, tmp);
- StrToPoint(xptr, tmp, &pt);
- MoveWindow(w, pt.h, pt.v, FALSE);
- } else
- handled = FALSE;
-
- HUnlock(h);
- return(handled);
- }
-
- Handle
- GetProp(StringPtr prop)
- {
- Handle h = 0;
- Point pt;
- Rect r;
- Str255 tmp;
-
- /* hypercard deals with loc and visible */
- if(pstrcmp(prop, "\pdithering") == 0){
- h = HStr((*th)->dither ? "true" : "false");
- } else if(pstrcmp(prop, "\pscrollbars") == 0){
- h = HStr((*th)->scrollbars ? "true" : "false");
- } else if(pstrcmp(prop, "\pglobalrect") == 0){
- pt.h = w->portRect.left;
- pt.v = w->portRect.top;
- LocalToGlobal(&pt);
- r.left = pt.h;
- r.top = pt.v;
- r.right = r.left + (w->portRect.right - w->portRect.left);
- r.bottom = r.top + (w->portRect.bottom - w->portRect.top);
- RectToStr(xptr, &r, tmp);
- h = PasToZero(xptr, tmp);
- } else if(pstrcmp(prop, "\pgloballoc") == 0){
- pt.h = w->portRect.left;
- pt.v = w->portRect.top;
- LocalToGlobal(&pt);
- PointToStr(xptr, pt, tmp);
- h = PasToZero(xptr, tmp);
- } else if(pstrcmp(prop, "\pscroll") == 0){
- pt.h = GetCtlValue((*th)->hScroll);
- pt.v = GetCtlValue((*th)->vScroll);
- PointToStr(xptr, pt, tmp);
- h = PasToZero(xptr, tmp);
- } else if(pstrcmp(prop, "\ppicturewidth") == 0){
- NumToString((long) (*th)->ti->imageWidth, tmp);
- h = PasToZero(xptr, tmp);
- } else if(pstrcmp(prop, "\ppictureheight") == 0){
- NumToString((long) (*th)->ti->imageLength, tmp);
- h = PasToZero(xptr, tmp);
- } else if(pstrcmp(prop, "\pscale") == 0){
- NumToString((long) NewScaleToOld((*th)->scale), tmp);
- h = PasToZero(xptr, tmp);
- } else if(pstrcmp(prop, "\pnscale") == 0){
- myftoa((*th)->scale, (char *)tmp);
- CtoPstr(tmp);
- h = PasToZero(xptr, tmp);
- } else if(pstrcmp(prop, "\ppicturedepth") == 0){
- NumToString((long)(*th)->ti->samplesPerPixel * (*th)->ti->bitsPerSample[0], tmp);
- h = PasToZero(xptr, tmp);
- }
-
- return(h);
- }
-
- long
- myatoi(char *s)
- {
- long l;
- char tmp[256];
-
- strncpy(tmp, s, sizeof(tmp)-1);
- CtoPstr(tmp);
- StringToNum(tmp, &l);
- return(l);
- }
-
- double
- myatof(char *s)
- {
- double d, denom;
-
- d = 0;
- while(isdigit(*s)){
- d *= 10;
- d += *s - '0';
- s++;
- }
-
- if(*s == '.'){
- s++;
- denom = 10;
- while(isdigit(*s)){
- d += (*s - '0') / denom;
- s++;
- denom *= 10;
- }
- }
-
- return(d);
- }
-
- /* only two digits after the decimal point */
- void
- myftoa(double d, char *s)
- {
- char f[256];
-
- myitoa((long) d, s);
-
- d -= (long) d;
- myitoa((long) (d * 100), f);
-
- strcat(s, ".");
- if(strlen(f) == 1)
- strcat(s, "0");
- strcat(s, f);
- }
-
- void
- myitoa(long i, char *a)
- {
- NumToString(i, a);
- PtoCstr(a);
- }